<template>
  <el-container class="document-container">
    <el-header>
      <el-page-header :icon="ArrowLeft" @back="goBack">
        <template #content>
          <span class="text-primary font-600 mr-3">在线文档浏览</span>
          <span v-if="fileExtension" class="file-type-badge">
            {{ fileExtension.toUpperCase() }}
          </span>
        </template>
      </el-page-header>
    </el-header>

    <el-main>
      <el-row :gutter="20">
        <el-col :span="16">
          <!-- 在线文档展示区域 -->
          <div class="document-viewer">
            <template v-if="isSupportedFormat">
              <template v-if="isImage">
                <img :src="documentUrl" alt="文档图片" class="document-image" />
              </template>
              <template v-show="isPdf">
                <!-- PDF容器始终存在，只是内容根据状态变化 -->
                <div class="pdf-container" ref="pdfContainer">
                  <div v-if="pdfLoading" class="loading-indicator">
                    <el-spinner size="large" />
                    <p class="mt-2">加载PDF中...</p>
                  </div>
                  <div v-else-if="pdfError" class="error-message">
                    <p>PDF加载失败，请尝试下载文件</p>
                    <el-button type="primary" @click="downloadFile" class="mt-2"
                      >下载文件
                    </el-button>
                  </div>
                  <!-- PDF页面将在renderPdf函数中动态创建 -->
                </div>
              </template>
              <template v-if="isWord">
                <div v-if="wordLoading" class="loading-indicator">
                  <el-spinner size="large" />
                  <p class="mt-2">加载Word文档中...</p>
                </div>
                <div v-else-if="wordError" class="error-message">
                  <p>Word文档加载失败，请尝试下载文件</p>
                  <el-button type="primary" @click="downloadFile" class="mt-2"
                    >下载文件
                  </el-button>
                </div>
                <div v-else ref="wordContainer" class="word-container"></div>
              </template>
              <template v-if="isText">
                <pre class="document-text">{{ textContent }}</pre>
              </template>
            </template>
            <template v-else>
              <div class="unsupported-message">
                <p>不支持在线浏览，请下载</p>
                <el-button type="primary" @click="downloadFile" class="mt-2"
                  >下载文件
                </el-button>
              </div>
            </template>
            <el-button type="primary" @click="downloadFile" class="download-btn"
              >下载文件
            </el-button>
          </div>
        </el-col>

        <el-col :span="8">
          <!-- 学习笔记 -->
          <el-card class="notes-card mb-3">
            <template #header>
              <div class="card-header">学习笔记</div>
            </template>
            <div class="qa-list">
              <div v-for="nt in notesList" :key="nt.id">
                <p>{{ nt.content }}</p>
                <el-divider></el-divider>
              </div>
            </div>
            <el-input
              type="textarea"
              :rows="5"
              placeholder="记录你的学习笔记..."
              v-model="notes"
            ></el-input>

            <div ref="notesEnd"></div>

            <el-button type="primary" class="mt-2" @click="saveNotes"
              >保存笔记
            </el-button>
          </el-card>

          <!-- 问题讨论 -->
          <el-card class="qa-card">
            <template #header>
              <div class="card-header">问题讨论</div>
            </template>
            <div class="qa-list">
              <div
                v-for="(qa, index) in qaList"
                :key="qa.id || index"
                class="qa-item"
              >
                <p><strong>Q:</strong> {{ qa.questions.content }}</p>
                <p v-for="ans in qa.answers">
                  <strong>A:</strong> {{ ans.content || "暂无回答" }}
                </p>

                <!-- 教师可以回答问题 -->
                <div v-if="isTeacher && !qa.answer" class="answer-form mt-2">
                  <el-input
                    type="textarea"
                    :rows="2"
                    placeholder="输入回答..."
                    v-model="qa.tempAnswer"
                    class="mb-2"
                  ></el-input>
                  <el-button
                    type="success"
                    size="small"
                    @click="answerQuestion(qa.questions.id, qa.tempAnswer)"
                  >
                    提交回答
                  </el-button>
                </div>
                <el-divider></el-divider>
              </div>
              <div ref="qaEnd"></div>
            </div>
            <el-input
              type="textarea"
              :rows="3"
              placeholder="提出你的问题..."
              v-model="newQuestion"
              class="mb-2"
            ></el-input>
            <el-button type="primary" @click="submitQuestion"
              >提交问题
            </el-button>
          </el-card>

          <!-- 下载按钮 -->
          <el-button
            type="primary"
            class="mt-3 w-100"
            @click="downloadDocument"
            :icon="Download"
          >
            下载文档
          </el-button>
        </el-col>
      </el-row>
    </el-main>
  </el-container>
</template>
<script setup>
import {
  ref,
  nextTick,
  onMounted,
  onUnmounted,
  computed,
  onBeforeUnmount,
} from "vue";
import { ArrowLeft, Download } from "@element-plus/icons-vue";
import { useRoute, useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import { useUserStore } from "@/stores/user";
import { useCourseStore } from "@/stores/course";
import common_util from "@/util/common_util";
import axios from "axios";
import * as pdfjsLib from "pdfjs-dist";
import { renderAsync } from "docx-preview";

// 设置PDF.js工作器
// pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;
// 配置 worker 路径为 CDN 地址
pdfjsLib.GlobalWorkerOptions.workerSrc =
  "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.worker.min.js";

const route = useRoute();
const router = useRouter();
const userStore = useUserStore();
const courseStore = useCourseStore();

// 获取当前用户ID和角色信息
const userId = computed(() => userStore.user?.id);
const isTeacher = computed(() => userStore.isTeacher);
const isStudent = computed(() => userStore.isStudent);

const documentUrl = ref(route.query.url ? route.query.url.toString() : "");
const courseId = ref(
  route.query.courseId ? parseInt(route.query.courseId) : null,
);
const fileExtension = ref("");
const isSupportedFormat = ref(false);
const isImage = ref(false);
const isPdf = ref(false);
const isWord = ref(false);
const isText = ref(false);
const textContent = ref("");
const notes = ref("");
const newQuestion = ref("");

// PDF相关状态
const pdfDoc = ref(null);
const pdfPages = ref(0);
const pdfLoading = ref(false);
const pdfError = ref(false);
const pdfContainer = ref(null); // 引用PDF容器元素

// Word相关状态
const wordLoading = ref(false);
const wordError = ref(false);
const wordContainer = ref(null);

// 使用courseStore中的notes数据
const notesList = computed(() => courseStore.notes || []);
// 使用courseStore中的questions数据
const qaList = computed(() => courseStore.questions || []);

const notesEnd = ref(null);
const qaEnd = ref(null);

const goBack = () => {
  router.go(-1);
};

const saveNotes = async () => {
  if (!notes.value.trim()) {
    ElMessage.warning("笔记内容不能为空！");
    return;
  }

  if (!userId.value || !courseId.value) {
    ElMessage.warning("用户信息或课程信息不完整，无法保存笔记");
    return;
  }

  try {
    // 使用courseStore的addNote方法保存笔记
    await courseStore.addNote(notes.value, userId.value, courseId.value);

    // 清空输入框
    notes.value = "";

    // 重新获取笔记列表
    await courseStore.getNotes(userId.value, courseId.value);

    nextTick(() => {
      notesEnd.value?.scrollIntoView({ behavior: "smooth" });
    });
  } catch (error) {
    console.error("保存笔记失败:", error);
    ElMessage.error("保存笔记失败，请稍后重试");
  }
};

const submitQuestion = async () => {
  if (!newQuestion.value.trim()) {
    ElMessage.warning("问题内容不能为空！");
    return;
  }

  if (!userId.value || !courseId.value) {
    ElMessage.warning("用户信息或课程信息不完整，无法提交问题");
    return;
  }

  try {
    // 使用common_util提交问题
    const content = newQuestion.value;
    await new Promise((resolve, reject) => {
      common_util.post(
        "/api/study/ask",
        {
          userId: userId.value,
          courseId: courseId.value,
          content: content,
        },
        {},
        (data) => {
          ElMessage.success("问题提交成功");
          resolve(data);
        },
        (message) => {
          ElMessage.error(`提交问题失败: ${message}`);
          reject(message);
        },
      );
    });

    // 清空输入框
    newQuestion.value = "";

    // 重新获取问题列表
    await courseStore.getQuestionAndAnswers(userId.value, courseId.value);

    nextTick(() => {
      qaEnd.value?.scrollIntoView({ behavior: "smooth" });
    });
  } catch (error) {
    console.error("提交问题失败:", error);
    ElMessage.error("提交问题失败，请稍后重试");
  }
};

// 教师回答问题
const answerQuestion = async (questionId, answerContent) => {
  if (!isTeacher.value) {
    ElMessage.warning("只有教师可以回答问题");
    return;
  }

  if (!answerContent || !answerContent.trim()) {
    ElMessage.warning("回答内容不能为空");
    return;
  }

  try {
    await courseStore.answerQuestion(answerContent, userId.value, questionId);

    // 重新获取问题列表
    await courseStore.getQuestionAndAnswers(userId.value, courseId.value);
  } catch (error) {
    console.error("回答问题失败:", error);
    ElMessage.error("回答问题失败，请稍后重试");
  }
};
// 下载文件
const downloadFile = () => {
  if (!documentUrl.value) {
    ElMessage.warning("文档URL不存在");
    return;
  }
  const link = document.createElement("a");
  link.href = documentUrl.value;
  link.download = documentUrl.value.split("/").pop() || "document";
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};

// 下载文档（与downloadFile相同，为了兼容模板中的调用）
const downloadDocument = downloadFile;

// 渲染PDF文档
const renderPdf = async () => {
  pdfLoading.value = true;
  pdfError.value = false;
  let pdf = null;
  
  try {
    // 确保PDF容器存在 - 使用多个nextTick和检查确保DOM已完全渲染
    for (let attempts = 0; attempts < 3; attempts++) {
      await nextTick();
      if (pdfContainer.value) break;
      // 短暂延迟，给DOM更多时间渲染
      await new Promise(resolve => setTimeout(resolve, 50));
    }
    
    if (!pdfContainer.value) {
      console.error('PDF容器元素不存在');
      pdfError.value = true;
      ElMessage.error('PDF容器元素不存在，无法渲染PDF');
      return;
    }
    
    // 加载PDF文档
    try {
      pdf = await pdfjsLib.getDocument(documentUrl.value).promise;
      pdfDoc.value = pdf;
      pdfPages.value = pdf.numPages;
    } catch (loadError) {
      console.error('PDF文档加载失败:', loadError);
      pdfError.value = true;
      ElMessage.error(`PDF文档加载失败: ${loadError.message || '未知错误'}`);
      return;
    }
    
    // 设置加载状态为false，这样v-if条件会移除加载指示器
    pdfLoading.value = false;
    
    // 安全地清空容器 - 使用try-catch包裹DOM操作
    try {
      if (pdfContainer.value) {
        // 移除所有子元素，但保留容器本身
        while (pdfContainer.value.firstChild) {
          pdfContainer.value.removeChild(pdfContainer.value.firstChild);
        }
      } else {
        throw new Error('PDF容器元素在清空时不存在');
      }
    } catch (clearError) {
      console.error('清空PDF容器时出错:', clearError);
      pdfError.value = true;
      return;
    }

    // 添加页面计数器
    let renderedPages = 0;
    let failedPages = 0;
    
    // 渲染所有页面
    for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
      try {
        // 再次检查容器是否存在
        if (!pdfContainer.value) {
          console.error(`渲染第${pageNum}页前PDF容器元素不存在`);
          break; // 如果容器不存在，停止渲染后续页面
        }
        
        const page = await pdf.getPage(pageNum);
        const scale = 1.2;
        const viewport = page.getViewport({ scale });

        // 创建canvas元素
        const canvas = document.createElement('canvas');
        const context = canvas.getContext('2d');
        canvas.width = viewport.width;
        canvas.height = viewport.height;
        canvas.className = 'pdf-page';

        const renderContext = {
          canvasContext: context,
          viewport: viewport
        };

        // 渲染PDF页面到canvas
        await page.render(renderContext).promise;
        
        // 使用try-catch包裹DOM操作
        try {
          // 再次检查容器是否存在
          if (pdfContainer.value) {
            pdfContainer.value.appendChild(canvas);
            renderedPages++;
          } else {
            throw new Error(`渲染第${pageNum}页时PDF容器元素不存在`);
          }
        } catch (appendError) {
          console.error(`添加第${pageNum}页到DOM时出错:`, appendError);
          failedPages++;
          // 继续尝试渲染下一页
        }
      } catch (pageError) {
        console.error(`渲染第${pageNum}页时出错:`, pageError);
        failedPages++;
        // 继续渲染下一页
      }
    }
    
    // 检查是否成功渲染了任何页面
    if (renderedPages === 0) {
      throw new Error('未能成功渲染任何PDF页面');
    }
    
    console.log(`PDF渲染完成，共渲染了${renderedPages}/${pdf.numPages}页`);
    if (failedPages > 0) {
      ElMessage.warning(`PDF文档加载完成，但有${failedPages}页渲染失败`);
    } else {
      ElMessage.success(`PDF文档加载完成，共${pdf.numPages}页`);
    }
  } catch (error) {
    console.error('PDF渲染错误:', error);
    pdfError.value = true;
    ElMessage.error(`PDF渲染失败: ${error.message || '未知错误'}`);
  } finally {
    pdfLoading.value = false;
  }
};

// 渲染Word文档
const renderWord = async () => {
  wordLoading.value = true;
  wordError.value = false;
  try {
    console.log("开始加载Word文档:", documentUrl.value);

    // 使用axios获取文档内容，设置为blob类型
    const response = await axios.get(documentUrl.value, {
      responseType: "blob",
      // 添加超时设置
      timeout: 30000,
      // 添加请求头，避免跨域问题
      headers: {
        Accept: "application/octet-stream",
      },
    });

    const blob = response.data;
    console.log("Word文档下载成功，大小:", blob.size, "字节");

    // 确保容器元素存在
    await nextTick();
    if (!wordContainer.value) {
      throw new Error("Word容器元素不存在");
    }

    // 使用docx-preview渲染Word文档
    await renderAsync(blob, wordContainer.value, null, {
      className: "docx-container",
      inWrapper: true,
      ignoreWidth: false,
      ignoreHeight: false,
      ignoreFonts: false,
      breakPages: true,
      debug: false,
    });

    console.log("Word文档渲染成功");
    ElMessage.success("Word文档加载完成");
  } catch (error) {
    console.error("Word文档加载失败:", error);
    wordError.value = true;
    ElMessage.error(`Word文档加载失败: ${error.message || "未知错误"}`);
  } finally {
    wordLoading.value = false;
  }
};

// 加载文本文件
const loadTextFile = async () => {
  try {
    console.log("开始加载文本文件:", documentUrl.value);
    const response = await axios.get(documentUrl.value, {
      // 添加超时设置
      timeout: 15000,
      // 添加请求头，避免跨域问题
      headers: {
        Accept:
          "text/plain,text/html,text/css,text/javascript,application/json",
      },
    });
    textContent.value = response.data;
    console.log("文本文件加载成功，大小:", textContent.value.length, "字符");
    ElMessage.success("文本文件加载完成");
  } catch (error) {
    console.error("获取文本内容失败:", error);
    ElMessage.error(`文本文件加载失败: ${error.message || "未知错误"}`);
    isSupportedFormat.value = false; // 如果获取失败，视为不支持
  }
};

onMounted(async () => {
  try {
    // 确保文档URL存在
    if (!documentUrl.value) {
      console.error("文档URL不存在");
      ElMessage.warning("文档URL不存在，请检查链接是否正确");
      return;
    }

    console.log("文档URL:", documentUrl.value);

    // 解析文件扩展名
    const urlParts = documentUrl.value.split(".");
    if (urlParts.length < 2) {
      console.error("无法解析文件扩展名");
      ElMessage.warning("无法识别文件类型，请确保URL包含文件扩展名");
      return;
    }
    
    fileExtension.value = urlParts[urlParts.length - 1].toLowerCase();
    console.log("文件扩展名:", fileExtension.value);

    // 定义支持的格式
    const supportedImages = ["jpg", "jpeg", "png", "gif", "bmp", "svg", "webp"];
    const supportedTexts = [
      "txt",
      "md",
      "csv",
      "html",
      "htm",
      "css",
      "js",
      "json",
      "xml",
      "log",
    ];

    isImage.value = supportedImages.includes(fileExtension.value);
    isPdf.value = fileExtension.value === "pdf";
    isWord.value =
      fileExtension.value === "docx" || fileExtension.value === "doc";
    isText.value = supportedTexts.includes(fileExtension.value);
    isSupportedFormat.value =
      isImage.value || isPdf.value || isWord.value || isText.value;

    console.log("文件类型检测结果:", {
      isImage: isImage.value,
      isPdf: isPdf.value,
      isWord: isWord.value,
      isText: isText.value,
      isSupportedFormat: isSupportedFormat.value,
    });

    // 根据文件类型加载内容
    if (isPdf.value) {
      // 确保PDF容器已经在DOM中渲染
      await nextTick();
      
      // 再次检查isPdf状态，确保在等待期间没有变化
      if (!isPdf.value) {
        console.error("尝试渲染PDF但isPdf为false");
        return;
      }
      
      // 检查PDF容器状态
      console.log("PDF容器状态:", pdfContainer.value ? "存在" : "不存在");
      
      // 使用try-catch包裹渲染函数调用
      try {
        // 调用渲染函数
        await renderPdf();
      } catch (renderError) {
        console.error("PDF渲染过程中发生错误:", renderError);
        ElMessage.error(`PDF渲染失败: ${renderError.message || '未知错误'}`);
      }
    } else if (isWord.value) {
      try {
        await renderWord();
      } catch (wordError) {
        console.error("Word文档渲染失败:", wordError);
        ElMessage.error(`Word文档渲染失败: ${wordError.message || '未知错误'}`);
      }
    } else if (isText.value) {
      try {
        await loadTextFile();
      } catch (textError) {
        console.error("文本文件加载失败:", textError);
        ElMessage.error(`文本文件加载失败: ${textError.message || '未知错误'}`);
      }
    } else if (isImage.value) {
      console.log("图片文件将直接通过img标签显示");
      ElMessage.success("图片加载中");
    } else {
      console.log("不支持的文件格式:", fileExtension.value);
      ElMessage.warning(
        `不支持在线预览 ${fileExtension.value} 格式，请下载后查看`,
      );
    }

    // 页面加载时直接报告100%进度
    if (userId.value && courseId.value) {
      try {
        // 假设文档总时长为100秒，当前时间设为100秒表示100%
        await courseStore.updateProgress(userId.value, 100);
        console.log("进度已报告: 100%");
      } catch (progressError) {
        console.error("报告进度失败:", progressError);
      }
    }

    // 加载笔记和问题
    if (userId.value && courseId.value) {
      try {
        await Promise.all([
          courseStore.getNotes(userId.value, courseId.value),
          courseStore.getQuestionAndAnswers(userId.value, courseId.value)
        ]);
      } catch (loadError) {
        console.error("加载笔记和问题失败:", loadError);
      }
    }
  } catch (error) {
    console.error("组件挂载过程中发生错误:", error);
    ElMessage.error("页面加载过程中发生错误，请刷新重试");
  }
});

onBeforeUnmount(() => {
  try {
    // 清理PDF资源
    if (pdfDoc.value) {
      try {
        pdfDoc.value.destroy();
      } catch (destroyError) {
        console.error('清理PDF资源时出错:', destroyError);
      } finally {
        pdfDoc.value = null;
      }
    }

    // 安全地清空PDF容器
    if (pdfContainer.value) {
      try {
        // 使用更安全的方式清空容器
        while (pdfContainer.value.firstChild) {
          pdfContainer.value.removeChild(pdfContainer.value.firstChild);
        }
      } catch (clearError) {
        console.error('清空PDF容器时出错:', clearError);
      }
    }
  } catch (error) {
    console.error('组件卸载过程中发生错误:', error);
  }
});
</script>
<style scoped>
.document-container {
  height: 100vh;
  padding: 20px;
  background-color: #f9f9f9;
}

.document-viewer {
  width: 100%;
  min-height: 70vh;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
  background-color: #fff;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  overflow: auto;
  position: sticky;
  top: 0;
  z-index: 10;
  padding: 20px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.document-iframe {
  width: 100%;
  height: 100%;
  border: none;
}

.document-image {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
  border: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.document-text {
  width: 100%;
  height: 100%;
  white-space: pre-wrap;
  overflow: auto;
  font-family: monospace;
  padding: 15px;
  border: 1px solid #eee;
  border-radius: 4px;
  background-color: #fafafa;
  color: #333;
  line-height: 1.5;
}

.unsupported-message,
.loading-indicator,
.error-message {
  text-align: center;
  padding: 40px 20px;
  width: 100%;
  color: #666;
}

.loading-indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 200px;
}

.download-btn {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 20;
}

.notes-card,
.qa-card {
  margin-bottom: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
}

.notes-card:hover,
.qa-card:hover {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}

.card-header {
  font-size: 18px;
  font-weight: bold;
  color: #409eff;
  padding: 12px 20px;
  border-bottom: 1px solid #ebeef5;
}

.qa-item {
  margin-bottom: 15px;
  padding: 10px;
  border-radius: 6px;
  background-color: #f9f9f9;
}

.qa-item p {
  margin: 5px 0;
  line-height: 1.5;
}

.qa-list {
  max-height: 250px;
  overflow-y: auto;
  margin-bottom: 15px;
  padding: 10px;
  border-radius: 4px;
  background-color: #fff;
}

.qa-list::-webkit-scrollbar {
  width: 6px;
}

.qa-list::-webkit-scrollbar-thumb {
  background-color: #ddd;
  border-radius: 3px;
}

.qa-list::-webkit-scrollbar-track {
  background-color: #f5f5f5;
}

.pdf-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px 0;
}

.pdf-page {
  max-width: 100%;
  margin-bottom: 20px;
  border: 1px solid #f0f0f0;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  background-color: white;
}

.word-container {
  width: 100%;
  min-height: 70vh;
  border: 1px solid #e0e0e0;
  padding: 20px;
}

.docx-container {
  width: 100%;
  box-sizing: border-box;
}

.docx-container p {
  margin: 0 0 1em 0;
  line-height: 1.6;
}

.docx-container h1,
.docx-container h2,
.docx-container h3 {
  margin-top: 1.5em;
  margin-bottom: 0.5em;
}

.file-type-badge {
  display: inline-block;
  padding: 2px 8px;
  background-color: #409eff;
  color: white;
  border-radius: 4px;
  font-size: 12px;
  font-weight: bold;
  margin-left: 10px;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .document-container {
    padding: 10px;
  }

  .document-viewer {
    min-height: 50vh;
  }

  .qa-list,
  .notes-card {
    max-height: 200px;
  }
}
</style>
